package com.quectel.cms.controller.alarm;


import com.quectel.business.common.alarm.DataProcessingComponent;
import com.quectel.cms.controller.BaseController;
import com.quectel.cms.util.SessionHolder;
import com.quectel.constant.core.alarm.AlarmConstants;
import com.quectel.util.aspect.log.annotation.Log;
import com.quectel.constant.global.annotation.RequirePermissions;
import com.quectel.core.module.alarm.dto.AlarmRuleDto;
import com.quectel.core.module.alarm.dto.HandAlarmRuleInfo;
import com.quectel.core.module.alarm.service.AlarmEventRecordService;
import com.quectel.core.module.alarm.service.AlarmRuleService;
import com.quectel.core.module.device.dto.DeviceCurrentAlarmDto;
import com.quectel.core.module.device.dto.DeviceDto;
import com.quectel.core.module.device.service.DeviceCategoryService;
import com.quectel.core.module.device.service.DeviceCurrentAlarmService;
import com.quectel.core.module.device.service.DeviceService;
import com.quectel.core.module.device.service.DeviceTypeService;
import com.quectel.util.common.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @author caolu
 * @email louis.cao@quectel.com
 * @date 2019-06-14 15:14:16
 */
@RestController
@RequestMapping("deviceCurrentAlarm")
@Tag(name = "DeviceCurrentAlarmController", description = "设备当前告警相关api")
public class DeviceCurrentAlarmController extends BaseController {

    @DubboReference
    private DeviceCurrentAlarmService deviceCurrentAlarmService;
    @DubboReference
    private DeviceService deviceService;
    @DubboReference
    private DeviceTypeService deviceTypeService;
    @DubboReference
    private AlarmEventRecordService eventRecordService;
    @DubboReference
    private AlarmRuleService alarmRuleService;
    @DubboReference
    private DeviceCategoryService deviceCategoryService;
    @Autowired
    private DataProcessingComponent dataProcessingComponent;

    /**
     * 告警恢复
     */
    @PostMapping("restore")
    @RequirePermissions(values = "deviceCurrentAlarm:restore")
    @Operation(summary = "通过当前设备告警记录id,对记录进行告警恢复")
    @Log(express = "恢复告警")
    public Response<Object> recover(@RequestBody Long[] ids) {
        for (Long id : ids) {
            DeviceCurrentAlarmDto deviceCurrentAlarmDto = deviceCurrentAlarmService.selectById(id);
            if (deviceCurrentAlarmDto == null) {
                continue;
            }
            dataProcessingComponent.recoverCurrentAlarm(deviceCurrentAlarmDto, AlarmConstants.ALARM_MANUAL_CLOSE_TYPE);

            //告警状态重置
            DeviceDto deviceDto = deviceService.selectById(deviceCurrentAlarmDto.getDeviceId());
            dataProcessingComponent.updateAlarmStatusAndMergeLastData(deviceDto, new HashMap<>());

            if (StringUtils.isNotBlank(deviceCurrentAlarmDto.getAlarmDetailJson())) {
                //处理事件或者工单
                HandAlarmRuleInfo handAlarmRuleInfo = new HandAlarmRuleInfo();
                handAlarmRuleInfo.setAlarmConformLevel(AlarmConstants.ALARM_NO);
                handAlarmRuleInfo.setAlarmRuleDto(JacksonUtils.parse(deviceCurrentAlarmDto.getAlarmDetailJson(), AlarmRuleDto.class));


                dataProcessingComponent.handleAlarmEventAndWorkOrder(deviceDto,
                        new DataProcessingComponent.HandleAlarmResp(
                                new ArrayList<>(Arrays.asList(handAlarmRuleInfo)),
                                deviceCurrentAlarmService.queryByDeviceId(deviceCurrentAlarmDto.getDeviceId())
                        )
                );

            }

        }
        return Response.ok();
    }

    /**
     * 列表
     */
    @GetMapping("exportExcel")
    @RequirePermissions(values = "deviceCurrentAlarm:list")
    @Operation(summary = "导出设备当前告警记录")
    @Log(express = "导出告警记录")
    public void exportExcel(@RequestParam Map<String, Object> params, HttpServletResponse hresp) {
        Request request = Request.configParamsNotPage(params);

        super.fillAuthorityData(params);
        Long tenantId = SessionHolder.getSysUser().getTenantId();

        if (StringUtils.isNotBlank(request.getString("imei"))) {
            DeviceDto deviceInfo = deviceService.selectCacheByImei(request.getString("imei"), tenantId);
            if (deviceInfo == null) {
                params.put("deviceId", "-1");
            } else {
                params.put("deviceId", deviceInfo.getId());
            }
        }
        if (params.containsKey("level")) {
            if (StringUtils.isEmpty(params.get("level").toString())) {
                params.remove("level");
            } else {
                params.put("level", Short.valueOf(params.get("level").toString()));
            }
        }

        List<DeviceCurrentAlarmDto> result = new ArrayList<>();
        int pageNo = 0;
        params.put("limit", 1000);
        while (true) {
            params.put("offset", pageNo++ * 1000);
            List<DeviceCurrentAlarmDto> list = deviceCurrentAlarmService.queryList(params);
            if (org.apache.commons.collections4.CollectionUtils.isEmpty(list)) {
                break;
            }
            result.addAll(list);
            if (list.size() < 1000) {
                break;
            }
        }
        String[] headers = new String[]{"设备IMEI", "设备种类", "设备类型", "告警原因", "告警条件", "告警数据", "告警时间"};
        List<String[]> dataList = new ArrayList<>();
        for (DeviceCurrentAlarmDto data : result) {
            String[] item = new String[headers.length];
            item[0] = data.getImei();
            item[1] = data.getDeviceCategory().getName();
            item[2] = data.getDeviceType().getName();
            item[3] = "";
            if (StringUtils.isNotBlank(data.getAlarmDetailJson())) {
                item[3] = JacksonUtils.parse(data.getAlarmDetailJson()).get("name").asText();
            }
            item[4] = data.getRecData();
            item[5] = "";
            if (StringUtils.isNotBlank(data.getAlarmDetailJson())) {
                AlarmRuleDto alarmRuleDto = JacksonUtils.parse(data.getAlarmDetailJson(), AlarmRuleDto.class);

                String temp = "";
                if (alarmRuleDto.getAlarmConditionList() != null) {
                    for (int i = 0; i < alarmRuleDto.getAlarmConditionList().size(); i++) {
                        if (i <= 0) {
                            temp = alarmRuleDto.getAlarmConditionList().get(i).getDeviceColumnCnName() + "(" + alarmRuleDto.getAlarmConditionList().get(i).getDeviceColumnEntityName() + ")"
                                    + alarmRuleDto.getAlarmConditionList().get(i).getCondition() + alarmRuleDto.getAlarmConditionList().get(i).getQuota();
                        } else {
                            temp = temp + "\n" + alarmRuleDto.getAlarmConditionList().get(i).getDeviceColumnCnName() + "(" + alarmRuleDto.getAlarmConditionList().get(i).getDeviceColumnEntityName() + ")"
                                    + alarmRuleDto.getAlarmConditionList().get(i).getCondition() + alarmRuleDto.getAlarmConditionList().get(i).getQuota();
                        }
                    }
                }
                item[5] = temp;

            }

            item[6] = DateUtils.format(data.getAlarmTime(), DateUtils.FormatType.COMMON);
            dataList.add(item);
        }
        POIUtils.exportExcel(hresp, "当前告警信息", headers, dataList, "当前告警信息");

    }

    /**
     * 查询告警数量
     */
    @GetMapping("queryAlarmCount")
    @Operation(summary = "查询当前设备告警的数量")
    public Response<Integer> queryAlarmCount(@RequestParam Map<String, Object> params) {
        Request request = Request.configParams(params);

        super.fillAuthorityData(params);

        int total = deviceCurrentAlarmService.queryTotal(params);
        return Response.<Integer>ok().wrap(total);
    }

    /**
     * 列表
     */
    @GetMapping("list")
    @RequirePermissions(values = "deviceCurrentAlarm:list")
    @Operation(summary = "设备当前告警记录的分页查询列表")
    public Response<Page<DeviceCurrentAlarmDto>> list(@RequestParam Map<String, Object> params) {
        Request request = Request.configParams(params);

        super.fillAuthorityData(params);
        Long tenantId = SessionHolder.getSysUser().getTenantId();

        if (StringUtils.isNotBlank(request.getString("imei"))) {
            DeviceDto deviceInfo = deviceService.selectCacheByImei(request.getString("imei"), tenantId);
            if (deviceInfo == null) {
                params.put("deviceId", "-1");
            } else {
                params.put("deviceId", deviceInfo.getId());
            }
        }
        if (params.containsKey("level")) {
            if (StringUtils.isEmpty(params.get("level").toString())) {
                params.remove("level");
            } else {
                params.put("level", Short.valueOf(params.get("level").toString()));
            }
        }
        int total = deviceCurrentAlarmService.queryTotal(params);
        List<DeviceCurrentAlarmDto> list = new ArrayList<>();
        if (total > 0) {
            list = deviceCurrentAlarmService.queryList(params);
        }
        Page<DeviceCurrentAlarmDto> page = new Page<>(request.getPageNo(), request.getPageSize(), total, list);
        return Response.<Page<DeviceCurrentAlarmDto>>ok().wrap(page);
    }


    /**
     * 信息
     */
    @GetMapping("info/{id}")
    @RequirePermissions(values = "deviceCurrentAlarm:info")
    @Operation(summary = "查询单条当前告警记录")
    public Response<DeviceCurrentAlarmDto> info(@PathVariable("id") Long id) {

        DeviceCurrentAlarmDto deviceCurrentAlarmDto = deviceCurrentAlarmService.selectById(id);

        return Response.<DeviceCurrentAlarmDto>ok().wrap(deviceCurrentAlarmDto);
    }

    /**
     * 保存
     */
    @PostMapping("save")
    @RequirePermissions(values = "deviceCurrentAlarm:edit")
    @Operation(summary = "保存单条当前告警记录")
    public Response<Object> save(@RequestBody @Validated DeviceCurrentAlarmDto deviceCurrentAlarmDto) {

        //填充基础数据
        fillSaveCommonData(deviceCurrentAlarmDto);

        deviceCurrentAlarmService.save(deviceCurrentAlarmDto);

        return Response.ok();
    }

    /**
     * 修改
     */
    @PostMapping("update")
    @RequirePermissions(values = "deviceCurrentAlarm:edit")
    @Operation(summary = "编辑单条当前告警记录")
    public Response<Object> update(@RequestBody @Validated DeviceCurrentAlarmDto deviceCurrentAlarmDto) {

        //填充基础数据
        fillEditCommonData(deviceCurrentAlarmDto);

        deviceCurrentAlarmService.updateById(deviceCurrentAlarmDto);

        return Response.ok();
    }

    /**
     * 删除
     */
    @PostMapping("delete")
    @RequirePermissions(values = "deviceCurrentAlarm:delete")
    @Operation(summary = "批量删除存在的当前告警记录")
    public Response<Object> delete(@RequestBody Long[] ids) {

        deviceCurrentAlarmService.deleteBatch(ids);

        return Response.ok();
    }
}
